/*
 * Copyright 2011 R.PREVOT.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package core;

import com.sun.awt.AWTUtilities;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;

/**
 * Display a notification in the bottom right corner of the screen
 * @author R.PREVOT
 */
public class Notif extends JWindow implements MouseListener {
    
    /**
     * The initial position
     */
    Point position;
    /**
     * The current Position of the window
     */
    Point currentPosition;
    
    /**
     * The screen size
     */
    Dimension screenSize;
    /**
     * The initial size of the window
     */
    Dimension size;
    /**
     * The current size
     */
    Dimension currentSize;
    
    /**
     * The actual fade ratio of the window
     */
    Float fadeRatio;
    
    private String message;
    
    private String title;
    
    private Icon icon;
    
    
    /**
     * elements
     */
    JPanel titlePan;
    JPanel contentPan;
    
    
    
    /**
     * Animation = UP: 1, DOWN : -1;
     */
    public int animation;
    
    /**
     * Static var for animation
     * cause i've got no memory in my mind... netbeans help me!
     */
    /**
     * Window is growingUp
     */
    static int UP = 1;
    /**
     * Window is fading out!
     */
    static int DOWN = -1;
    
    
    /**
     * Not yet!
     * @deprecated till i did't write thoses constructors
     * @param pos 
     */
    public Notif(Point pos){
        /*this(pos, new Dimension(200, 50));*/
        throw new IllegalArgumentException("Not implemented yet");
        
    }
    
    /**
     * Pf! No way!
     * @deprecated till i did't write thoses constructors
     * @param pos
     * @param size 
     */
    public Notif(Point pos, Dimension size){
        /*super();*/
        throw new IllegalArgumentException("Not implemented yet");
    }

    /**
     * Construct a notif in the bottom left corner of the screen!
     * @todo get title, message and type parameters
     * will draw special border and icon according to the type parameter
     */
    public Notif() {
        super();
        
        //initial animation
        this.animation = UP;
        
        //Toolkit to get the size of the screen and removing insets (task bar etc...)
        Toolkit kit = Toolkit.getDefaultToolkit();
        Insets insets = kit.getScreenInsets(getGraphicsConfiguration());
        screenSize = kit.getScreenSize();
        
        //initial size
        size = new Dimension(250, 100);
        //initial fadeRatio
        fadeRatio = new Float(1);
        
        //initialposition without insets and with 10px margin top & right
        position = new Point();
        position.x = screenSize.width - size.width - insets.left - insets.right - 10;
        position.y = screenSize.height - size.height - insets.top - insets.bottom - 10 ;
        
        // /!\ use clone to copy objects!
        //Setting the position to the initial position p^lus the height of the windows
        //starting point is so the botom left point of the window
        currentPosition = (Point)position.clone();
        currentPosition.y = position.y + size.height;
        
        //and so the height is null!
        currentSize = (Dimension)size.clone();
        currentSize.height = 0;
        
        //puttin the windows at its begin position
        this.setBounds(currentPosition.x, currentPosition.y, size.width, size.height);
        this.setVisible(true);
        
        message = "Test Message!";
        title = "Title!";
        
        initComponents();
        
        initEvents();
        
        //Starting the thread!
        new AnimaNotif(this);
    }
    
    private void initComponents(){
        setLayout(new BorderLayout());
        
        titlePan = new JPanel();
        titlePan.add(new JLabel(title));
        
        contentPan = new JPanel();
        contentPan.add(new JLabel(message));
        
        add(BorderLayout.NORTH, titlePan);
        add(BorderLayout.CENTER, contentPan);
    }
    
    private void initEvents(){
        //Allowing to click the window and managed other actions...
        this.addMouseListener(this);
    }
    
    /**
     * Grow the height of the windows and set the new bounds (move)
     * @todo find a way to grow always at the same speed (use ya brain dude!)
     * @return return true while it could be grown then false
     */
    public boolean growUp(){
        if(currentSize.height < size.height){
            currentSize.height++;
            currentPosition.y--;
            
            this.setBounds(currentPosition.x, currentPosition.y, currentSize.width, currentSize.height);
            return true;
        } else {
            return false;
        }
    }
    
    /**
     * decrease the y position of the windows and set the new bounds (move)
     * @todo find a way to fade always at the same speed
     * @return return true while it in the screen
     */
    private boolean fadeOut() {
        if(currentPosition.y <= screenSize.height){
            float numerator  = (float)(screenSize.getHeight() - currentPosition.getY());
            float denominator = (float)(screenSize.getHeight() - position.getY());
            fadeRatio = numerator / denominator;
            currentPosition.y++;
            AWTUtilities.setWindowOpacity(this, fadeRatio);
            
            this.setBounds(currentPosition.x, currentPosition.y, currentSize.width, currentSize.height);
            return true;
        } else {
            return false;
        }
        
    }

    /**
     * launch the changing animation
     * @todo put the tempo here
     * @todo find a better way
     * @param b 
     */
    private void setIsDisplay(boolean b) {
        if(b){
            this.animation = -1;
            new AnimaNotif(this);
        }
    }

    /**
     * Debug POWA!
     * @return ya mama!
     */
    @Override
    public String toString() {
        return "Notif{" + "position=" + position + ", currentPosition=" + currentPosition + ", size=" + size + ", currentSize=" + currentSize + '}';
    }
    
    
    /**
     * Draw the border of the window
     * @todo display icon
     * @param g 
     */
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.drawRect(0, 0, this.currentSize.width -1, this.currentSize.height -1);
    }
    
    
    /**
     * Use to dispose the window prematurely
     * @todo manage actives threads
     * @param e 
     */
    @Override
    public void mouseClicked(MouseEvent e) {
        this.dispose();
    }

    /**
     * Not used!
     * @param e 
     */
    @Override
    public void mousePressed(MouseEvent e) {}

    /**
     * Not used!
     * @param e 
     */
    @Override
    public void mouseReleased(MouseEvent e) {}

    /**
     * Not used!
     * @param e 
     */
    @Override
    public void mouseEntered(MouseEvent e) {}

    /**
     * Not used!
     * @param e 
     */
    @Override
    public void mouseExited(MouseEvent e) {}
   
    /**
     * Thread animation!
     */
    public class AnimaNotif extends Thread{
        
        Notif daddy;

        /**
         * Construct the animation and let it knows his father
         * @param papa 
         */
        public AnimaNotif(Notif papa) {
            this.daddy = papa;
            start();
        }

        /**
         * Main loop!
         */
        @Override
        public void run() {
            try{
                if(daddy.animation == Notif.UP){
                    while(daddy.growUp()){
                        Thread.sleep(1);
                    }
                    Thread.sleep(2000);
                    this.daddy.setIsDisplay(true);
                } else {
                    while(daddy.fadeOut()){
                        Thread.sleep(10);
                    }
                    this.daddy.dispose();
                }
            
            } catch (InterruptedException ex) {}
        }
        
    }
    
}
